/*******************************************************************************

  Pilot Intelligence Library
    http://www.pilotintelligence.com/

  ----------------------------------------------------------------------------

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.

*******************************************************************************/


#include <stdio.h>

#include "base/debug/debug_config.h"
#include "osa++_poco.h"

namespace pi {


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

bool Thread::ourInitializedFlag     = false;
int64_t Thread::ourCount            = 0;


void Thread::_threadProc(void* param)
{
    Thread* thread = (Thread*)param;

    dbg_pt("thread = %llx, name = %s, myRunningFlag = %d, myRunnable = %llx\n",
           thread,
           thread->myName.c_str(), thread->myRunningFlag, thread->myRunnable);

    thread->myRunningFlag = true;
    thread->hasJoined = false;

    ourCount++;

    if (thread->myRunnable)
        thread->myRunnable->threadFunc();
    else
        thread->threadFunc();

    thread->myRunningFlag = false;
    thread->hasJoined = true;

    ourCount--;
}


bool Thread::init(void)
{
    ourCount = 0;
    return true;
}

Thread::Thread()
{
    // initialize thread variables
    if( !ourInitializedFlag ) {
        init();
        ourInitializedFlag = true;
    }

    myRunnable = NULL;
    myRunningFlag = false;
    myStopFlag = true;

    hasJoined = true;

    myName = "thread-default";
}


/// Returns the mininum operating system-specific priority value,
/// which can be passed to setOSPriority().
int Thread::getMinOSPriority(void)
{
    return Poco::Thread::getMinOSPriority();
}

/// Returns the maximum operating system-specific priority value,
/// which can be passed to setOSPriority().
int Thread::getMaxOSPriority(void)
{
    return Poco::Thread::getMaxOSPriority();
}


/// Returns the Thread object for the currently active thread.
/// If the current thread is the main thread, 0 is returned.
///
/// FIXME: not implemented
Thread* Thread::current(void)
{
    return NULL;
}

/// Returns the native thread ID for the current thread.
uint64_t Thread::currentTid(void)
{
    return (uint64_t) Poco::Thread::currentTid();
}


//! Returns how many threads are actually running, not including the main thread.
unsigned int Thread::count(void)
{
    return ourCount;
}

//! Tell the current thread to sleep for milli milliseconds
void Thread::sleep(unsigned int milli)
{
    Poco::Thread::sleep(milli);
}

//! Tell the current thread to yield the processor.
void Thread::yield(void)
{
    Poco::Thread::yield();
}



////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

///
/// \brief Get current process's ID number
///
/// \return process ID number
///
uint64_t osa_getPID(void)
{
    return (uint64_t) Poco::Process::id();
}

///
/// \brief Get current thread's ID number
///
/// \return thread ID number
///
uint64_t osa_getTID(void)
{
    return (uint64_t) Poco::Thread::currentTid();
}



////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

static int g_isRunning = 1;

int isRunning(void)
{
    return g_isRunning;
}

int setStop(int s)
{
    g_isRunning = s;

    return g_isRunning;
}


} // end of namespace pi
